package cn.net.isir.controller.manager;

import cn.net.isir.service2.*;
import com.github.pagehelper.PageInfo;
import cn.net.isir.common.ResultObject;
import cn.net.isir.common.TokenManager;
import cn.net.isir.common.config.AlipayConfig;
import cn.net.isir.core.BasicModel;
import cn.net.isir.entity.AlipayAgent;
import cn.net.isir.entity.BusinessInfo;
import cn.net.isir.entity.Payment;
import cn.net.isir.entity.Shop;
import cn.net.isir.utils.QRUtils;
import cn.net.isir.utils.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @author liuxubo
 * @filename ThirdPartyPayController.java
 * @package cn.net.isir.controller.manager
 * @email lxb@isir.net.cn
 * @date 2018/11/29
 * @comment
 * @since 1.8
 */
@RestController
@RequestMapping("/tppay")
public class ThirdPartyPayController {
    //声明日志对象
    private static Logger logger = Logger.getLogger(ThirdPartyPayController.class);
    @Resource
    private ShopService shopService;
    @Resource
    private AlipayAuthService alipayAuthService;
    @Resource
    private AlipayOpenAgentFacetofaceSignService alipayOpenAgentFacetofaceSignService;
    @Resource
    private AlipayAgentService alipayAgentService;
    @Resource
    private BusinessInfoService businessInfoService;
    @Resource
    private PaymentService paymentService;

    /**
     * 获取第三方支付列表
     *
     * @return 第三方支付列表
     */
    @RequestMapping(value = "/paymentList", method = RequestMethod.GET)
    public ResultObject payList() {
        //查询所管理店铺
        List<Shop> shopList = shopService.selectListByUser(new BasicModel()).getList();
        logger.info("查询出的管理店铺");
        shopList.forEach(item -> logger.info(item.getId()));
        //查询管理店铺中包含的支付宝支付id和微信支付id
        Set<String> paymentIds = new HashSet<>();
        shopList.forEach(item -> {
            //获取微信支付方式
            String wxpayMerchantId = item.getWxpayMerchantId();
            if (wxpayMerchantId != null && !"0".equals(wxpayMerchantId)) {
                paymentIds.add(wxpayMerchantId);
            }
            //获取支付宝支付方式
            String alipayMerchantId = item.getAlipayMerchantId();
            if (alipayMerchantId != null && !"0".equals(alipayMerchantId)) {
                paymentIds.add(alipayMerchantId);
            }
        });

        //根据支付方式的添加人
        Payment p2 = new Payment();
        p2.setCreateUser(TokenManager.getTokenId());
        List<Payment> pList2 = paymentService.selectList(p2);
        pList2.forEach(item -> paymentIds.add(item.getId()));

        //更新状态
        alipayOpenAgentFacetofaceSignService.updateOpenAgentFacetofaceSignStatus(new ArrayList<>(paymentIds));
        //增加使用此支付方式的店铺列表
        List<Payment> paymentList = new ArrayList<>();
        paymentIds.forEach(item -> {
            Payment payment = paymentService.selectByPrimaryKey(item);
            if (payment == null) {
                return;
            }
            //查找到使用此列表的店铺
            Shop shop = new Shop();
            if (payment.getType().equals("wxpay")) {
                shop.setWxpayMerchantId(payment.getId());
            }
            if (payment.getType().equals("alipay")) {
                shop.setAlipayMerchantId(payment.getId());
            }
            List<Shop> shops = shopService.selectList(shop);
            List<String> shopIds = new ArrayList<>();
            shops.forEach(item2 -> shopIds.add(item2.getId()));
            payment.setShopIdList(shopIds);
            paymentList.add(payment);
        });

        /*
         * 如果有审核通过的，则返回响应的签约url
         */
        paymentList.forEach(item -> {
            if ("2".equals(item.getSignStatus())) {
                AlipayAgent agent = alipayAgentService.selectByPrimaryKey(item.getAgentInfoId());
                item.setSign_confirm_url(agent.getSign_confirm_url());
            }
        });

        return new ResultObject(200, "success", new PageInfo<>(paymentList));
    }


    /**
     * 增加微信支付
     *
     * @param payment 实体类信息
     * @return 添加结果
     */
    @RequestMapping(value = "/addWxPay", method = RequestMethod.POST)
    public ResultObject addWxPay(@RequestBody Payment payment) {
        ResultObject ro = new ResultObject();
        if (StringUtils.isBlank(payment.getSignAccount())) {
            ro.set(500, "微信商户号为空", null);
            return ro;
        }
        String shopids = payment.getShopIds();

        //新增微信支付
        Payment payment1 = new Payment();
        String name = payment.getName();
        if (StringUtils.isBlank(name)) {
            name = "微信支付-" + payment.getSignAccount();
        }
        payment1.setName(name);
        payment1.setType("wxpay");
        payment1.setAuthStatus("1");
        payment1.setSignStatus("3");
        payment1.setSignAccount(payment.getSignAccount());
        payment1.setPaymentStatus("1");
        payment1.setCreateUser(TokenManager.getTokenId());
        paymentService.insert(payment1);

        // 如果没有选择店铺，则直接返回
        if (StringUtils.isBlank(shopids)) {
            return new ResultObject(200, "success", payment.getSignAccount());
        }

        //如果有店铺，循环给每个店铺设置支付
        if (StringUtils.isNotBlank(shopids)) {
            List<String> shopIdList = Arrays.asList(shopids.split(","));
            if (shopIdList.size() > 0) {
                for (String shopId : shopIdList) {
                    Shop shop = shopService.selectByPrimaryKey(shopId);
                    if (shop != null) {
                        shop.setWxpayMerchantId(payment1.getId());
                        shopService.update(shop);
                    }
                }
            }
        }

        ro.set(200, "success", shopids.length());
        return ro;
    }

    /**
     * 获取支付信息
     *
     * @param id 支付id
     * @return 支付信息
     */
    @RequestMapping(value = "/getPayInfo/{id}", method = RequestMethod.GET)
    public ResultObject getPayInfo(@PathVariable String id) {
        Payment payment = paymentService.selectByPrimaryKey(id);
        Shop shop = new Shop();
        shop.setWxpayMerchantId(id);
        List<String> shopIdList = new ArrayList<>();
        shopService.selectList(shop).forEach(item -> shopIdList.add(item.getId()));
        payment.setShopIdList(shopIdList);
        return new ResultObject(200, "success", payment);
    }


    /**
     * 编辑支付(用于微信支付和支付宝通过的支付的信息修改：重新选择店铺，设置别名)
     *
     * @param payment 实体类信息
     * @return 添加结果
     */
    @RequestMapping(value = "/savePayment", method = RequestMethod.PUT)
    public ResultObject savePayment(@RequestBody Payment payment) {
        Payment paymentRes = paymentService.selectByPrimaryKey(payment.getId());
        String payType = paymentRes.getType();//wxpay--alipay

        Shop shop1 = new Shop();
//        shop1.setWxpayMerchantId(payment.getId());
        if (payType.equals("wxpay")) {
            shop1.setWxpayMerchantId(payment.getId());
        }
        if (payType.equals("alipay")) {
            shop1.setAlipayMerchantId(payment.getId());
        }
        List<Shop> shopResList = shopService.selectList(shop1);

        if (StringUtils.isBlank(payment.getSignAccount())) {
            return new ResultObject(500, "商户号为空", null);
        }
        if (StringUtils.isBlank(payment.getId())) {
            return new ResultObject(500, "沒有id", null);
        }
        paymentService.update(payment);

        List<String> shopList = Arrays.asList(payment.getShopIds().split(","));
        if (shopList.size() > 0) {
            //查询原来存在，现在不存在的（原先选中了，现在没有选中）
            for (Shop res : shopResList) {
                boolean isExist = false;
                for (String newShopId : shopList) {
                    if (newShopId.equals(res.getId())) {
                        isExist = true;
                        break;
                    }
                }
                //不存在说明是去掉了
                if (!isExist) {
                    if (payType.equals("wxpay")) {
                        res.setWxpayMerchantId("0");
                    }
                    if (payType.equals("alipay")) {
                        res.setAlipayMerchantId("0");
                    }
                    shopService.update(res);
                }
            }

            //查询新增的部分
            for (String newShopId : shopList) {
                boolean isExist = false;
                for (Shop res : shopResList) {
                    if (newShopId.equals(res.getId())) {
                        isExist = true;
                        break;
                    }
                }
                //不存在则说明是新增的
                if (!isExist) {
                    Shop shop = shopService.selectByPrimaryKey(newShopId);
//                    shop.setWxpayMerchantId(payment.getId());
                    if (payType.equals("wxpay")) {
                        shop.setWxpayMerchantId(payment.getId());
                    }
                    if (payType.equals("alipay")) {
                        shop.setAlipayMerchantId(payment.getId());
                    }
                    shopService.update(shop);
                }
            }
        }

        return new ResultObject(200, "success", payment.getId());
    }

    /**
     * 获取授权二维码(授权给第三方)
     *
     * @param uuid     第三方支付，uuid码，用于在用户扫码之后，绑定到具体的支付手段
     * @param response 输出流，输出一张二维码图片
     */
    @RequestMapping(value = "/getAlipayAuthQRCode/{uuid}", method = RequestMethod.GET)
    public void getAlipayAuthQRCode(@PathVariable String uuid, HttpServletResponse response) {
//        Shop shop = shopService.selectByPrimaryKey(shopid);
//        if (shop == null) {
//            return;
//        }
        if (StringUtils.isBlank(uuid)) {
            response.setStatus(401);
            return;
        }
        Payment payment = new Payment();
        payment.setComment(uuid);
        int count = paymentService.selectCount(payment);
        if (count > 0) {
            response.setStatus(401);
            return;
        }
        String content = AlipayConfig.getAuth_url_pay() + uuid;
        try {
            response.setContentType("image");
            QRUtils.encodeToStream(content, QRUtils.ImageFormat.png, response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 支付宝授权回调页面(第三方授权后回调)
     *
     * @param request 请求，从中能获取app_id和app_auth_code
     * @return 用户手机客户端，跳转到成功页面
     */
    @RequestMapping(value = "/alipayAuthRedirect")
    public ModelAndView alipayAuthRedirect(HttpServletRequest request) {
//        logger.info(shopId);
        String appId = request.getParameter("app_id");
        String uuid = request.getParameter("shopId");
        String appAuthCode = request.getParameter("app_auth_code");

        logger.info("支付宝授权回调");
        logger.info("appId:" + appId);
        logger.info("uuid:" + uuid);
        logger.info("appAuthCode:" + appAuthCode);

        // 支付宝授权接口 https://docs.open.alipay.com/20160728150111277227/intro
        ModelAndView modelAndView = new ModelAndView("authSuccess");
        request.setAttribute("alipayId", StringUtils.getCurrentTimeMillis());

        //新增支付宝支付
        Payment payment1 = new Payment();
        payment1.setName("支付宝支付" + appId);
        payment1.setType("alipay");
        payment1.setAuthStatus("1");
        payment1.setSignStatus("0");
        payment1.setPaymentStatus("1");
//        payment1.setCreateUser(TokenManager.getTokenId());
        payment1.setComment(uuid);//使用此uuid字段，作为扫描二维码的关联内容
        paymentService.insert(payment1);

        String userId = null;//TokenManager.getTokenId();
        ResultObject resultObject =
                alipayAuthService.alipayAuthRedirect(userId, appId, payment1.getId(), appAuthCode);
        if (resultObject.getResult() == 200) {
            userId = (String) resultObject.getObject();
            request.setAttribute("alipayId", userId);
            return modelAndView;
        }
        return null;
    }

    /**
     * 检查是否已经扫码
     *
     * @param uuid uuid
     * @return 结果
     */
    @RequestMapping(value = "/checkAuthStatus/{uuid}", method = RequestMethod.GET)
    public ResultObject checkAuthStatus(@PathVariable String uuid) {
        Payment payment = new Payment();
        payment.setComment(uuid);
        payment = paymentService.selectOne(payment);
        if (payment == null) {
            return new ResultObject(300, "success", null);
        }
        //更新创建人
        payment.setCreateUser(TokenManager.getTokenId());
        paymentService.update(payment);
        return new ResultObject(200, "success", payment.getId());
    }

    /**
     * 提交当面付信息
     *
     * @param businessInfo 当面付信息
     * @return 返回添加信息
     */
    @RequestMapping(value = "/submitAlipaymentInfo", method = RequestMethod.POST)
    public ResultObject addAlipayment(@RequestBody BusinessInfo businessInfo) {

        //新增运营信息
        businessInfoService.insert(businessInfo);
        //查询该支付方式，是否已存在
        String id = businessInfo.getPaymentId();
        if (StringUtils.isBlank(businessInfo.getPaymentId())) {
            return new ResultObject(500, "paymentId is null", null);
        }
        logger.info("paymentId:" + businessInfo.getPaymentId());
        Payment payment = paymentService.selectByPrimaryKey(id);
        //更新别名
        if (StringUtils.isNotBlank(businessInfo.getAlias())) {
            logger.info("修改别名：" + businessInfo.getAlias());
            payment.setName(businessInfo.getAlias());
        }
        //修改签约账户
        payment.setSignAccount(businessInfo.getLicenseNo());
        paymentService.update(payment);

        String user = payment.getAuthAccount();

        //绑定店铺
        if (StringUtils.isNotBlank(businessInfo.getShopId())) {
            logger.info("获取到的shopid:" + businessInfo.getShopId());
            for (String shopId : businessInfo.getShopId().split(",")) {
                Shop shop = shopService.selectByPrimaryKey(shopId);
                shop.setAlipayMerchantId(payment.getId());
                shopService.update(shop);
            }
        }

        //如果之前已经签约过，则无须重新签约，可以直接签约成功
        Payment p = new Payment();
        p.setType("alipay");
        p.setAuthAccount(user);
        p.setSignStatus("3");
        List<Payment> pList = paymentService.selectList(p);
        // 设置支付方式的签约方式
        payment.setBindingSignInfoId(businessInfo.getId());
        // 更新资料绑定
        paymentService.update(payment);
        if (pList != null && pList.size() > 0) {
            //设置为已签约状态
            payment.setSignStatus("3");
            paymentService.update(payment);
            return new ResultObject(201, "success", null);
        }

        // 如果有正在签约的，也不可以再次提交资料了
        Payment p2 = new Payment();
        p2.setType("alipay");
        p2.setAuthAccount(user);
        p2.setSignStatus("1");//等待审核
        List<Payment> pList2 = paymentService.selectList(p2);
        if (pList2 != null && pList2.size() > 0) {
            return new ResultObject(502, "fail", null);
        }
        Payment p3 = new Payment();
        p3.setType("alipay");
        p3.setAuthAccount(user);
        p3.setSignStatus("2");//等待用户确认
        List<Payment> pList3 = paymentService.selectList(p3);
        if (pList3 != null && pList3.size() > 0) {
            return new ResultObject(502, "fail", null);
        }
        Payment p4 = new Payment();
        p4.setType("alipay");
        p4.setAuthAccount(user);
        p4.setSignStatus("4");//需要修改
        List<Payment> pList4 = paymentService.selectList(p4);
        if (pList4 != null && pList4.size() > 0) {
            return new ResultObject(502, "fail", null);
        }
        Payment p5 = new Payment();
        p5.setType("alipay");
        p5.setAuthAccount(user);
        p5.setSignStatus("5");//需要修改
        List<Payment> pList5 = paymentService.selectList(p5);
        if (pList5 != null && pList5.size() > 0) {
            return new ResultObject(502, "fail", null);
        }
        Payment p6 = new Payment();
        p5.setType("alipay");
        p5.setAuthAccount(user);
        p5.setSignStatus("6");//需要修改
        List<Payment> pList6 = paymentService.selectList(p6);
        if (pList6 != null && pList6.size() > 0) {
            return new ResultObject(502, "fail", null);
        }
        //如果没签署过，则重新提交资料
        alipayOpenAgentFacetofaceSignService.
                submitOpenAgentFacetofaceSignInfo(businessInfo);

        return new ResultObject(200, "success", null);
    }

    /**
     * 保存当面付信息
     *
     * @param businessInfo 当面付信息
     * @return 返回添加信息
     */
    @RequestMapping(value = "/reSubmitAlipaymentInfo", method = RequestMethod.POST)
    public ResultObject saveAlipayment(@RequestBody BusinessInfo businessInfo) {
        if (StringUtils.isBlank(businessInfo.getAlias())) {
            return new ResultObject(500, "success", null);
        }

        // 判断是新增还是更新
        if (StringUtils.isBlank(businessInfo.getId())) {
            businessInfoService.insert(businessInfo);
        } else {
            // 更新当面付签约信息
            businessInfoService.update(businessInfo);
        }

        //查询该支付方式，是否已存在
        String id = businessInfo.getPaymentId();
        if (StringUtils.isBlank(id)) {
            return new ResultObject(500, "no paymentId found.", null);
        }
        Payment payment = paymentService.selectByPrimaryKey(id);
        if (payment == null) {
            return new ResultObject(500, "no payment found.", null);
        }
        String user = payment.getAuthAccount();
        //更新别名
        if (StringUtils.isNotBlank(businessInfo.getAlias())) {
            payment.setName(businessInfo.getAlias());
        }
        //修改签约账户
        payment.setSignAccount(businessInfo.getLicenseNo());
        paymentService.update(payment);
        String payType = payment.getType();//wxpay--alipay

        //重新绑定店铺
        Shop shop1 = new Shop();
        shop1.setAlipayMerchantId(payment.getId());
        List<Shop> shopResList = shopService.selectList(shop1);

        List<String> shopList = Arrays.asList(businessInfo.getShopId().split(","));
        if (shopList.size() > 0) {
            //查询原来存在，现在不存在的（原先选中了，现在没有选中）
            for (Shop res : shopResList) {
                boolean isExist = false;
                for (String newShopId : shopList) {
                    if (newShopId.equals(res.getId())) {
                        isExist = true;
                        break;
                    }
                }
                //不存在说明是去掉了
                if (!isExist) {
//                    res.setWxpayMerchantId("0");
//                    if (payType.equals("wxpay")) {
//                        res.setWxpayMerchantId("0");
//                    }
                    if (payType.equals("alipay")) {
                        res.setAlipayMerchantId("0");
                    }
                    shopService.update(res);
                }
            }

            //查询新增的部分
            for (String newShopId : shopList) {
                boolean isExist = false;
                for (Shop res : shopResList) {
                    if (newShopId.equals(res.getId())) {
                        isExist = true;
                        break;
                    }
                }
                //不存在则说明是新增的
                if (!isExist) {
                    Shop shop = shopService.selectByPrimaryKey(newShopId);
//                    shop.setWxpayMerchantId(payment.getId());
//                    if (payType.equals("wxpay")) {
//                        shop.setWxpayMerchantId(payment.getId());
//                    }
                    if (payType.equals("alipay")) {
                        shop.setAlipayMerchantId(payment.getId());
                    }
                    shopService.update(shop);
                }
            }
        }

        //重新提交资料
        alipayOpenAgentFacetofaceSignService.
                submitOpenAgentFacetofaceSignInfo(businessInfo);

        return new ResultObject(200, "success", null);
    }

    /**
     * 获取签约信息
     *
     * @param id 主键
     * @return 获取签约信息
     */
    @RequestMapping(value = "/getPayment/{id}", method = RequestMethod.GET)
    public ResultObject getPayment(@PathVariable String id) {
        Payment payment = paymentService.selectByPrimaryKey(id);
        String infoId = payment.getBindingSignInfoId();
        if (StringUtils.isBlank(infoId)) {
            return new ResultObject(300, "success", null);
        }
        BusinessInfo businessInfo = businessInfoService.selectByPrimaryKey(infoId);
        return new ResultObject(200, "success", businessInfo);
    }


    /**
     * 提交当面付信息
     *
     * @param businessInfo 当面付信息
     * @return 返回添加信息
     */
    @RequestMapping(value = "/submitAlipayInfo", method = RequestMethod.POST)

    public ResultObject addAlipay(@RequestBody BusinessInfo businessInfo) {

        String shopid = businessInfo.getShopId();
        Shop shop = shopService.selectByPrimaryKey(shopid);

        if (shop == null) {
            return new ResultObject(500, "fail", "没有此店铺");
        }

        //是否已签约
        int signStatus = Integer.parseInt(shop.getAlipaySignStatus());
        if (StringUtils.isNotBlank(shop.getAlipayBusinessInfo())
                && (signStatus == 1 || signStatus == 2)) {
            return new ResultObject(501, "fail", "isAlreadySign");
        }

        //判断是否已经新增
//        if (shop.getAlipayBusinessInfo() != null || "1".equals(shop.getAlipaySignStatus())) {
//            return new ResultObject(500, "fail", businessInfo);
//        }

        //新增运营信息
        businessInfoService.insert(businessInfo);

        if (StringUtils.isBlank(businessInfo.getId())) {
            return new ResultObject(500, "save sign fail", null);
        }

        // 店铺更新签约信息id
        shop.setAlipayBusinessInfo(businessInfo.getId());
        shopService.update(shop);

        //如果已经签约了（说明跟其他用户添加的支付宝是同一个账号，则无需审核签约资料，直接可通过审核）
        if (signStatus == 3) {
            return new ResultObject(201, "success", "您的支付宝账户已有签约信息，此次签约无需审核，签约成功！");
        }

        shop.setAlipaySignStatus("1");//1表示已保存未提交
        shopService.update(shop);

//        return alipayOpenAgentFacetofaceSignService.saveOpenAgentFacetofaceSignInfo(shop, businessInfo);
        return null;
        //根据用户的授权状态，判断是否要提交资料到支付宝
        //1.保存用户信息businessInfo

        //2.店铺信息中保存商户运营信息id
        //3.判断店铺信息中，是否已经授权，如果没有授权，则不提交到支付宝
    }
}
